﻿using Architecture.Domain.Service.CityServices;
using Architecture.Domain.Service.CountyService;
using Architecture.Domain.Service.LeaveServices;
using Architecture.Domain.Service.MenuRoleServices;
using Architecture.Domain.Service.MenuServices;
using Architecture.Domain.Service.ProvinceServices;
using Architecture.Domain.Service.RoleServices;
using Architecture.Domain.Service.UserInfoRoleServices;
using Architecture.Domain.Service.UserInfoServices;
using Architecture.Repository.Impl;
using Architecture.Repository.Impl.Traceability;
using Architecture.Repository.Interface;
using Architecture.Repository.Interface.Traceability;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Traceability.Domain.Service.AdditiveServices;
using Traceability.Domain.Service.AuxiliaryMaterialsServices;
using Traceability.Domain.Service.BreedService;
using Traceability.Domain.Service.DeepProcessingServices;
using Traceability.Domain.Service.EnterpriseServices;
using Traceability.Domain.Service.PackagingMaterialsServices;
using Traceability.Domain.Service.PictureService;
using Traceability.Domain.Service.RawMaterialServices;
using Traceability.Domain.Service.ShoppingNameService;
using Traceability.Domain.Service.ShoppingServices;
using Traceability.Domain.Service.SlaughterServices;
using Traceability.Domain.Service.TraceabilitiesServices;

namespace Architecture.API.Extension
{
    /// <summary>
    /// 静态扩展类
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// this 扩展语法
        /// string 代表被扩展的类型
        /// </summary>
        /// <param name="str">扩展方法传入的值</param>
        /// <returns>返回转换后的值</returns>
        public static int ToInt(this string str)
        {
            int result;
            if (int.TryParse(str, out result)) // true 类型转换成功
            {
                return result;
            }
            else
            {
                return -9999;
            }
        }

        /// <summary>
        /// 获取身份证的出生日期
        /// </summary>
        /// <param name="idCard">身份证</param>
        /// <returns>返回出生日期</returns>
        public static string GetBirthday(this string idCard)
        {
            return idCard.Substring(6, 8);
        }

        ///// <summary>
        ///// 上下文扩展方法
        ///// </summary>
        ///// <typeparam name="TDbContext">上下文泛型类</typeparam>
        ///// <param name="services">服务集合</param>
        ///// <param name="connectionString">连接字符串</param>
        ///// <param name="enableSqlLog">是否启用sql日志</param>
        ///// <returns></returns>
        //public static IServiceCollection AddDbContextService<TDbContext>(this IServiceCollection services, string? connectionString, bool enableSqlLog) where TDbContext : DbContext
        //{
        //    //传入的上下文
        //    return services.AddDbContext<TDbContext>(builder =>
        //    {
        //        //默认使用微软sqlserver 可切换成MySQL、PostgreSQL等
        //        //connectionString为连接字符串
        //        builder.UseSqlServer(connectionString, action =>
        //        {
        //            action.EnableRetryOnFailure(
        //                //最大重试次数
        //                maxRetryCount: 10,
        //                //最大重试间隔时间
        //                maxRetryDelay: TimeSpan.FromSeconds(60),
        //                //是否在日志中显示失败的sql语句
        //                errorNumbersToAdd: null);
        //        }).EnableSensitiveDataLogging();
        //        //enableSalLog为是否启用sql日志
        //        //只有在开发环境下才启用sql日志
        //        if (enableSqlLog)
        //        {
        //            //启用sql日志
        //            builder.UseLoggerFactory(LoggerFactory.Create(configure =>
        //            {
        //                //过滤日志
        //                configure.AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information)
        //                //打印到控制台
        //                .AddConsole();
        //            }));
        //        }
        //    });
        //}

        /// <summary>
        /// 上下文扩展方法
        /// </summary>
        /// <typeparam name="TDbContext">上下文泛型类</typeparam>
        /// <param name="services">服务集合</param>
        /// <param name="connectionString">连接字符串</param>
        /// <param name="enableSqlLog">是否启用sql日志</param>
        /// <returns></returns>
        public static IServiceCollection AddDbContextService<TDbContext>(this IServiceCollection services, string connectionString, bool enableSqlLog) where TDbContext : DbContext
        {
            //传入的上下文
            return services.AddDbContext<TDbContext>(builder =>
            {
                //默认使用微软sqlserver 可切换成MySQL、PostgreSQL等
                //connectionString为连接字符串
                builder.UseSqlServer(connectionString, action =>
                {
                    action.EnableRetryOnFailure(
                        //最大重试次数
                        maxRetryCount: 10,
                        //最大重试间隔时间
                        maxRetryDelay: TimeSpan.FromSeconds(60),
                        //是否在日志中显示失败的sql语句
                        errorNumbersToAdd: null);
                }).EnableSensitiveDataLogging();
                //enableSalLog为是否启用sql日志
                //只有在开发环境下才启用sql日志
                if (enableSqlLog)
                {
                    //启用sql日志
                    builder.UseLoggerFactory(LoggerFactory.Create(configure =>
                    {
                        //过滤日志
                        configure
                        .AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information)
                        //打印到控制台
                        .AddConsole();
                    }));
                }
            });
        }

        /// <summary>
        /// service 扩展方法
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <returns></returns>
        public static IServiceCollection AddService(this IServiceCollection services)
        {
            //仓储
            services.AddScoped<IUserInfoRepository, UserInfoRepository>();
            services.AddScoped<IProvinceRepository, ProvinceRepository>();
            services.AddScoped<ICityRepository, CityRepository>();
            services.AddScoped<ICountryRepository, CountryRepository>();
            services.AddScoped<IRoleRepository, RoleRepository>();
            services.AddScoped<IUserInfoRoleRepository, UserInfoRoleRepository>();
            services.AddScoped<IMenuRepository, MenuRepository>();
            services.AddScoped<IMenuRoleRepository, MenuRoleRepository>();
            services.AddScoped<ILeaveRepository, LeaveRepository>();

            //爱吃兔溯源仓储
            services.AddScoped<IShoppingNameRepository, ShoppingNameRepository>();
            services.AddScoped<IShoppingRepository, ShoppingRepository>();
            services.AddScoped<IPictureRepository, PictureRepository>();
            services.AddScoped<IBreedRepository, BreedRepository>();
            services.AddScoped<ITraceabilitiesRepoisotry, TraceabilitiesRepository>();
            services.AddScoped<IEnterpriseRepository, EnterpriseRepository>();
            services.AddScoped<ISlaughterReposiotry,SlaughterRepository>();
            services.AddScoped<IDeepProcessingRepository, DeepProcessingRepository>();
            services.AddScoped<IAdditivesRepository, AdditivesRepository>();
            services.AddScoped<IAuxiliaryMaterialsRepository, AuxiliaryMaterialsRepository>();
            services.AddScoped<IPackagingMaterialsRepository, PackagingMaterialsRepository>();
            services.AddScoped<IRawMaterialRepository, RawMaterialRepository>();

            //服务
            services.AddScoped<IUserInfoService, UserInfoService>();
            services.AddScoped<IProvinceService, ProvinceService>();
            services.AddScoped<ICityService, CityService>();
            services.AddScoped<ICountyService, CountyService>();
            services.AddScoped<IRoleService, RoleService>();
            services.AddScoped<IUserInfoRoleService, UserInfoRoleService>();
            services.AddScoped<IMenuService, MenuService>();
            services.AddScoped<IMenuRoleService, MenuRoleService>();
            services.AddScoped<ILeaveService, LeaveService>();


            //爱吃兔溯源服务
            services.AddScoped<IShoppingNameService, ShoppingNameService>();
            services.AddScoped<IShoppingService,ShoppingService>();
            services.AddScoped<IPictureService, PictureService>();
            services.AddScoped<IBreedService,BreedService>();
            services.AddScoped<ITraceabilitiesService, TraceabilitiesService>();
            services.AddScoped<IEnterpriseService, EnterpriseService>();
            services.AddScoped<ISlaughterService, SlaughterService>();
            services.AddScoped<IDeepProcessingService, DeepProcessingService>();
            services.AddScoped<IAdditiveService, AdditiveService>();
            services.AddScoped<IAuxiliaryMaterialsService, AuxiliaryMaterialsService>();
            services.AddScoped<IPackagingMaterialsService, PackagingMaterialsService>();
            services.AddScoped<IRawMaterialService, RawMaterialService>();

            return services; 
        }


        /// <summary>
        /// 注册JWT验证扩展方法
        /// </summary>
        /// <param name="dollection">服务集合</param>
        /// <param name="builder"></param>
        public static void AddJWT(this IServiceCollection dollection,WebApplicationBuilder builder)
        {
            //JWT验证开始
            builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
            {
                //取出密匙
                var secretByte = Encoding.UTF8.GetBytes(builder.Configuration["Authentication:SecretKey"]);
                //配置密匙
                options.TokenValidationParameters = new TokenValidationParameters()
                {
                    //验证发布者
                    ValidateIssuer = true,
                    ValidIssuer = builder.Configuration["Authentication:Issuer"],
                    //验证签发者
                    ValidateAudience = true,
                    ValidAudience = builder.Configuration["Authentication:Audience"],
                    //验证是否过期
                    ValidateLifetime = true,
                    //验证密匙
                    IssuerSigningKey = new SymmetricSecurityKey(secretByte)
                };
            });
        }

    }
}
